package models.robot

import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.JdbcProfile

import java.sql.Timestamp
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}

case class RobotTalk(id: Long =0, name: String = "", access: String = "", secret: String = "",status:Boolean=true, note: Option[String] = None)

case class RobotMassage(id: Long = System.currentTimeMillis() >>> 6, talkId: Long, title:String, msg: String, runtime: Timestamp, lostTime: Timestamp, sendStatus: Int = 0)

class RobotMessageRepository @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext)
  extends HasDatabaseConfigProvider[JdbcProfile] {
  //  private val dbConfig = dbConfigProvider.get[JdbcProfile]

  import dbConfig._
  import profile.api._

  private class RobotTalkTable(tag: Tag) extends Table[RobotTalk](tag, "ROBOT_TALKS".toUpperCase) {
    def id = column[Long]("id".toUpperCase, O.PrimaryKey)

    def name = column[String]("name".toUpperCase)

    def access = column[String]("access".toUpperCase)

    def secret = column[String]("secret".toUpperCase)

    def status = column[Boolean]("status".toUpperCase)

    def note = column[Option[String]]("note".toUpperCase)

    def * = (id, name, access, secret,status, note).<>((RobotTalk.apply _).tupled, RobotTalk.unapply)
  }

  private val talkTable = TableQuery[RobotTalkTable]


  private class RobotMsgTable(tag: Tag) extends Table[RobotMassage](tag, "ROBOT_MESSAGES".toUpperCase) {
    def id = column[Long]("id".toUpperCase, O.PrimaryKey)

    def talkId = column[Long]("talk_Id".toUpperCase)

    def title = column[String]("title".toUpperCase)

    def msg = column[String]("message".toUpperCase)

    def runtime = column[Timestamp]("run_time".toUpperCase)

    def losttime = column[Timestamp]("lost_time".toUpperCase)

    def sendStatus = column[Int]("status".toUpperCase)

    def * = (id, talkId,title, msg, runtime, losttime, sendStatus).<>((RobotMassage.apply _).tupled, RobotMassage.unapply)
  }

  private val msgTable = TableQuery[RobotMsgTable]

  //

  def talkFindAll() = db.run {
    talkTable.map(f => (f.id, f.name)).result
  }

  def talkAllList(talk: RobotTalk, page: Int = 0, limit: Int = 10) = {
    val f = talkTable
//      .filterOpt(talk.id)(_.id === _)
      .filterIf(talk.name.nonEmpty)(_.name like s"%${talk.name}%")
      .filterIf(talk.access.nonEmpty)(_.access === talk.access)
      .filterOpt(talk.note)(_.note like _)
    val res = f.sortBy(_.id).drop(page * limit).take(limit).map(f => f).result
    val total = f.length.result
    db.run(res).zip(db.run(total))
  }

//

  def msgCreate(msg:RobotMassage) = db.run{
    msgTable.filter(_.id === msg.id).exists.result
  }.flatMap{
    m=>
      if (m) Future(msg.id)
      else db.run(msgTable += msg)
  }

  def msgTableAllList(talkId:Long = 0,title:String = "",pDateStr: String = "", pStatus: Int = -1, page: Int = 0, limit: Int = 10) = {
    val dtformat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    val status = msgTable
      .filterIf(talkId != 0 )(_.talkId === talkId)
      .filterIf(pStatus >= 0)(_.sendStatus === pStatus)
      .filterIf(title.nonEmpty)(_.title === title)
    val f = if (pDateStr.length < 40) {
      status
    } else {
      val datestart = Option(Timestamp.valueOf(LocalDateTime.parse(pDateStr.substring(0, 19))))
      val dateend = Option(Timestamp.valueOf(LocalDateTime.parse(pDateStr.substring(22))))
      status
        .filterOpt(datestart)(_.runtime >= _)
        .filterOpt(dateend)(_.runtime <= _)
    }
    val res = f.sortBy(_.id).drop(limit * page).take(limit).map(f => f).result
    val total = f.length.result
    db.run(res).zip(db.run(total))
  }

  def msgTableDelete(idArr: Array[Long]) = db.run {
    val msgByID = for {
      i <- Parameters[Long]
      msg <- msgTable if msg.id === i
    } yield msg


    msgTable.filter(_.id inSet (idArr.toSet)).map(f => f).result

  }
}
